package es.amh.data;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;

import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.extensions.Recurrence;
import com.google.gdata.data.extensions.Reminder;
import com.google.gdata.data.extensions.Reminder.Method;

/**
 * Almacena una entrada de calendario que almacena la información relativa al
 * cumpleaños. Las características es que tiene un nombre y una fecha y que
 * siempre se repite anualmente.
 * 
 * Otras características: <br>
 * <li>No es un quickadd
 * 
 * //TODO personalizar la fecha
 * 
 * Su plantilla es
 * 
 * <br>
 * <br> <li>Title --> "Name" 's + birthday <li>body --> Today is the Name 's +
 * birtdhay, don't forget it. AmH designed
 * 
 * @author ahiges
 * 
 */
public class BirthdayEntry {

	private String name;

	private String date;

	private CalendarEventEntry entry;

	private final static int year;

	private final static String currentDate;

	private final static String partOfTitle = "'s birthday";

	static {

		SimpleDateFormat dateformatYYYYMMDD = new SimpleDateFormat("yyyyMMdd");

		Calendar c = GregorianCalendar.getInstance();
		year = c.get(Calendar.YEAR);

		StringBuilder nowYYYYMMDD = new StringBuilder(
				dateformatYYYYMMDD.format(c.getTime()));
		currentDate = nowYYYYMMDD + "";
	}

	public CalendarEventEntry getEntry() {
		return entry;
	}

	public void setEntry(CalendarEventEntry entry) {
		this.entry = entry;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	/**
	 * Crea un cumpleaños desde una entrada
	 * 
	 * @param _entry
	 */
	public BirthdayEntry(CalendarEventEntry _entry) {
		this.entry = _entry;
		this.name = entry.getTitle().getPlainText().replace(partOfTitle, "");
		String recurrence = entry.getRecurrence().getValue();
		String[] auxDate = recurrence.split("\n");
		this.date = auxDate[0].replace("DTSTART;VALUE=DATE:", "");
	}

	/**
	 * Create a birthday entry just with the _name and _date, no alarm is set
	 * 
	 * @param _name
	 * @param _date
	 */
	public BirthdayEntry(String _name, String _date, Boolean _emailReminder,
			Boolean _smsReminder, Boolean _popUpReminder) {
		name = _name;

		entry = new CalendarEventEntry();
		// Title and content
		entry.setTitle(new PlainTextConstruct(name + partOfTitle));
		entry.setContent(new PlainTextConstruct(
				"Today is the "
						+ name
						+ "'s birthday, don't forget to publish a comment on his/her facebook XD"));

		// Date
		_date = getValidDate(_date);
		String firstOcurrence = getFirstOccurrenceDate(_date);
		this.date = firstOcurrence;
		String recurData = "DTSTART;VALUE=DATE:" + firstOcurrence + "\r\n"
				+ "RRULE:FREQ=YEARLY;UNTIL=21000101\r\n";

		Recurrence recur = new Recurrence();
		recur.setValue(recurData);
		entry.setRecurrence(recur);

		// Config event
		entry.setQuickAdd(false);

		if (_emailReminder) {
			addEmailReminder(0);
		}

		if (_smsReminder) {
			addSMSReminder(0);
		}

		if (_popUpReminder) {
			addPopUPReminder(0);
		}
	}

	/**
	 * Hay diferentes formatos de fecha en google, este método adapta todos para
	 * que tengan el mismo formato
	 * 
	 * @param _date
	 * @return
	 */
	private String getValidDate(String _date) {
		if (_date.contains("--")) {
			_date = _date.replace("--", year + "-");
		}
		return _date;
	}

	/**
	 * Get the first occurrence date base on the current and the birthday date
	 * 
	 * @param _date
	 * 
	 * @return first occurrence
	 */
	private String getFirstOccurrenceDate(String _date) {
		String[] parseDate = _date.split("-");
		String firstOccurrence = year + parseDate[1] + parseDate[2];

		int first = Integer.parseInt(firstOccurrence);
		int current = Integer.parseInt(currentDate);

		if (first < current) {
			return (year + 1) + parseDate[1] + parseDate[2];
		} else {
			return firstOccurrence;
		}

	}

	/**
	 * Add an email reminder _minutes minutes before the 00:00 of the birthday
	 * 
	 * @param _minutes
	 */
	public void addEmailReminder(int _minutes) {
		int reminderMinutes = _minutes;
		Method methodType = Method.EMAIL;

		Reminder reminder = new Reminder();
		reminder.setMinutes(reminderMinutes);
		reminder.setMethod(methodType);

		entry.getReminder().add(reminder);
	}

	/**
	 * Add an SMS reminder _minutes minutes before the 00:00 of the birthday
	 * 
	 * @param _minutes
	 */
	public void addSMSReminder(int _minutes) {
		int reminderMinutes = _minutes;
		Method methodType = Method.SMS;

		Reminder reminder = new Reminder();
		reminder.setMinutes(reminderMinutes);
		reminder.setMethod(methodType);

		entry.getReminder().add(reminder);
	}

	/**
	 * Add an pop-up reminder _minutes minutes before the 00:00 of the birthday
	 * 
	 * @param _minutes
	 */
	public void addPopUPReminder(int _minutes) {
		int reminderMinutes = _minutes;
		Method methodType = Method.ALERT;

		Reminder reminder = new Reminder();
		reminder.setMinutes(reminderMinutes);
		reminder.setMethod(methodType);

		entry.getReminder().add(reminder);
	}

	@Override
	public boolean equals(Object obj) {
		try {
			BirthdayEntry be2 = (BirthdayEntry) obj;
			if (be2.getName().equalsIgnoreCase(name)) {
				return true;
			}
			return false;
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public String toString() {
		return name + "/" + date;
	}

	/**
	 * Decide si es necesario o no actualizar una entrada de cumpleaños
	 * @param b entrada con la que me tengo que comparar
	 * @return true si es necesaria actualización, false en caso contrario
	 */
	public boolean needUpdate(BirthdayEntry b) {
		return !(b.getDate().equals(date));
	}

}
